﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ReactiveUI.Fody.Helpers;
using Common.Utils;
using Common.Entitys.CommonLogs;
using Common.ViewModels.Messages;
using Jint.Runtime.Debugger;
using System.Windows.Documents;
using System.Runtime.ConstrainedExecution;

namespace Common.ViewModels
{
    /// <summary>
    /// 片区(有池子、通道。上料位  下料位,这里片区调度使用站点锁 运动锁,离开解锁，站点具有了方向性。实现跨站点调度,这里采用保守方案。解锁完才能运动,通道有了方向,Point3D定方向。这里还是那个逻辑。、
    /// 小车必然停在站点，小车不停在站点，带来的问题解决消耗时间过多,这里动态的办法)
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class 片区 : BaseViewModel
    {

        public 片区()
        {
            //订阅所属工位的请求调度信号()
            MessageAggregator<WorkStationRequestMsg>.Subscribe(OnWorkStationRequestMsg);
        }

        /// <summary>
        /// 当前请求的消息
        /// </summary>
        [Reactive]
        public List<WorkStationRequestMsg> WorkStationRequestMsgs { get; set; } = new List<WorkStationRequestMsg>();

        private readonly object m_LockWorkStationRequestMsgs = new object();

        private void OnWorkStationRequestMsg(WorkStationRequestMsg msg)
        {
            lock (m_LockWorkStationRequestMsgs)
            {
                WorkStationRequestMsgs.Add(msg);
            }
        }

        [Reactive] public string Name { get; set; }

        [Reactive] public string Description { get; set; }

        [Reactive] public double 当前运力 { get; set; }

        [Reactive] public double 所需运力 { get; set; }

        /// <summary>
        /// 摆渡通道
        /// </summary>
        [Reactive] public PassVM PassVM { get; set; }

        /// <summary>
        /// 片区所有的池子
        /// </summary>
        [Reactive] public ObservableCollection<池子> 池子s { get; set; } = new() { };

        /// <summary>
        /// 工作的池子
        /// </summary>
        [Reactive] public ObservableCollection<池子> 工作池子 { get; set; } = new() { };

        /// <summary>
        /// 上料池子(片区修改后不再改动)
        /// </summary>
        [Reactive] public ObservableCollection<池子> 上料池子 { get; set; } = new() { };

        /// <summary>
        /// 中间池子(片区修改后不再改动)
        /// </summary>
        [Reactive] public ObservableCollection<池子> 中间上料存放池子 { get; set; } = new() { };

        /// <summary>
        /// 中间下料池子(弄完之后放在下料池子里面，等待第一个小车把它运走)
        /// </summary>
        [Reactive] public ObservableCollection<池子> 中间下料存放池子 { get; set; } = new() { };

        /// <summary>
        /// 下料池子(片区修改后不再变动)
        /// </summary>
        [Reactive] public ObservableCollection<池子> 下料池子 { get; set; } = new() { };

        /// <summary>
        /// 小车
        /// </summary>
        [Reactive] public List<Car> Cars { get; set; } = new();

        /// <summary>
        /// 工位站点(有序的)
        /// </summary>
        [Reactive] public List<Station> Stations { get; set; } = new() { };

        /// <summary>
        /// 工位列表
        /// </summary>
        [Reactive] public List<WorkStation> WorkStations { get; set; } = new() { };

        /// <summary>
        /// 小车1
        /// </summary>
        [Reactive] public Car Car1 { get; set; }

        [Reactive] public double Car1FreePos { get; set; } = 1700;



        /// <summary>
        /// 小车2
        /// </summary>
        [Reactive]
        public Car Car2 { get; set; } 

        [Reactive] public double Car2FreePos { get; set; } = 2900;

        [Reactive] public int CarCount { get; set; } = 1;

        /// <summary>
        /// 是否继续运行
        /// </summary>
        [Reactive] public bool IsContinueRun { get; set; } = true;

        /// <summary>
        /// 工件锁,工件加入
        /// </summary>
        private readonly object m_LockLis工件s = new();

        /// <summary>
        /// 系统里面的工件
        /// </summary>
        [JsonIgnore]
        public List<工件> Lis工件s { get; set; } = new();

        [Reactive]
        public Station 公共Station { get; set; }

        /// <summary>
        /// 初始化片区
        /// </summary>
        public void Init()
        {
            //添加小车
            Car1 = new Car() { Name = $"M{ProductLine.Instance.Cars.Count + 1}" };
            ProductLine.Instance.Cars.Add(Car1);
            if (CarCount == 2)
            {
                Car2 = new Car() { Name = $"M{ProductLine.Instance.Cars.Count + 1}" };
                ProductLine.Instance.Cars.Add(Car2);
            }
        }

        public void StartTask()
        {
            Task.Factory.StartNew(Start, TaskCreationOptions.LongRunning);
            //工件进入站点
        }

        public void Start()
        {
            while (true)
            {
                DealContinueRun();
                DealStop();
                //工位上 工件将要完成时,规划一个小车过来，小车在忙就等待小车空闲。碎片化处理 
                //当某个片区的料上完的时候,可能放在中间临时存放卡槽。
                //工件上有完整的工作链条,入工件，将工件放入指定站点时，工件进入了系统 //发送消息
                //工件包含了下一个片区的信息。片区规划在片区歇息。
                //工件在当前片区不能查到信息时,会前往下一个片区。
                //这里对工件进行循环 不对工位进行循环了,入站涉及到移交工件操作



            }
        }

        public void Deal工件()
        {

        }



        public void DealStop()
        {
            //while (true)
            //{
            //    if(ProductLine.Instance.i)
            //}
        }

        public void DealContinueRun()
        {
            while (true)
            {
                if (!this.IsContinueRun)
                {
                    break;
                }
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 根据站点选择小车
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public Car GetStationCar(Station station)
        {
            if (Car2 == null)
            {
                return Car1;
            }


            for (int i = 0; i < Stations.Count; i++)
            {

                if (station != Stations[i])
                {
                    continue;
                }
                if (i < 3)
                {
                    return Car1;
                }
                else
                {
                    return Car2;
                }
            }

            return Car1;
        }

        /// <summary>
        /// 摆渡列表(带小车的摆渡
        /// </summary>
        [Reactive] public List<BoatVM> BoatVMs { get; set; } = new();


        private readonly object m_Lock上料槽位 = new();

        private readonly object m_Lock下料槽位 = new();

        private readonly object m_Lock工作槽位 = new();

        /// <summary>
        /// 获取上料的槽位
        /// </summary>
        /// <returns></returns>
        public WorkStation Get上料(out string error)
        {
            error = "";
            lock (m_Lock上料槽位)
            {
                foreach (var cz in 上料池子)
                {
                    foreach (var item in cz.Works)
                    {
                        if (item.是否有料)
                        {
                            return item;
                        }
                    }
                }
            }
            error = "暂时找不到空的槽位";//找不到空的槽位意味着要等待
            return null;
        }

        /// <summary>
        /// 获取下料的槽位(上下料的槽位在两侧)
        /// </summary>
        /// <param name="error"></param>
        /// <returns></returns>
        public WorkStation Get下料(WorkStation workStation, out string error)
        {
            error = "";
            lock (m_Lock下料槽位)
            {
                List<WorkStation> works = new List<WorkStation>();
                foreach (var cz in 下料池子)
                {
                    foreach (var item in cz.Works)
                    {
                        if (item.是否有料)
                        {
                            return item;
                        }
                    }
                }

                if (works.Count == 0)
                {
                    error = "暂时找不到空的槽位";
                    return null;
                }

                //计算最小值
                //WorkStation use=
                //foreach (var work in works)
                //{

                //}
            }
            error = "暂时找不到空的槽位";//找不到空的槽位意味着要等待 正常情况不允许出现  一旦出现 完犊子
            return null;
        }

        /// <summary>
        /// 调度小车(优先从片区上获取)
        /// </summary>
        /// <param name="workStation"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public Car GetCar(WorkStation workStation)
        {
            //error = "";
            //调度最近的空闲小车(从片区内调度一个最近的空闲小车 持续性)
            return Car1;
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="workStation"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public WorkStation Get工作(WorkStation workStation, out string error)
        {
            error = "";
            //以当前站点为核心 调度最近站点的小车
            //调度最近站点的池子
            List<WorkStation> works = new List<WorkStation> { };//新建工位
            foreach (var cz in this.工作池子)
            {
                foreach (var item in cz.Works)
                {
                    if (!item.是否有料)
                    {
                        continue;
                    }

                }
            }
            return workStation;
        }



        /// <summary>
        /// 片区调度
        /// </summary>
        public void Deal()
        {
            while (true)
            {
                try
                {
                    List<WorkStationRequestMsg> msgs = new();
                    //加锁
                    lock (m_LockWorkStationRequestMsgs)
                    {
                        msgs.AddRange(this.WorkStationRequestMsgs);
                    }

                    if (msgs.Count == 0)
                    {
                        Thread.Sleep(100);
                        continue;
                    }

                    this.当前运力 = this.Cars.FindAll(x => !x.IsLock).Count;//当前运力


                    this.所需运力 = msgs.Count;//当前需要的运力

                    //考虑跨区域调度
                    if (this.当前运力 == 0)
                    {
                        Thread.Sleep(100);
                        continue;
                    }

                    //根据时间进行排序
                    msgs.Sort();


                    foreach (var item in msgs)
                    {
                        Car car = GetNearCar(item, out string error);
                        if (car != null)
                        {
                            //调度摆渡上的小车移动到指定站点(位置)

                        }
                    }



                    //根据调度请求时间 调度出调
                    //调度系统 就近原则 就
                    var first = msgs[0];
                    for (int i = 1; i < msgs.Count; i++)
                    {
                        var iMsg = msgs[i];
                        if (first.DateTime > iMsg.DateTime)
                        {
                            first = iMsg;
                        }
                    }

                    //这里需要确定是由工件 选择调度 还是片区信息选择调度 选择工件调度  小车一定能调度过来,选择片区调度  优先处理时间问题
                    //这里面临一个问题,小车不能调度到此处的问题。
                    foreach (var car in Cars)
                    {
                        if (car.IsLock)
                        {

                        }
                    }

                }
                catch (Exception e)
                {
                    MessageAggregator<ErrorMsg>.Publish($"片区{this.Name} 调度出现异常 {e}");
                    //LogHelp.AddLog<ErrorLogEntity>($"片区{this.Name} 调度出现异常 {e}");
                }
            }
        }

        /// <summary>
        /// 处理(这里采用单线程)
        /// </summary>
        public void Deal2()
        {
            while (true)
            {
                IEnumerable<工件> 待处理工件s;
                lock (m_LockLis工件s)
                {
                    //整理出待处理的工件
                    待处理工件s = Lis工件s.Where(x => x.IsWaitMove);
                }

                //没有待处理工件,原地休息
                if (待处理工件s.Count() == 0)
                {
                    Thread.Sleep(100);
                    continue;
                }

                // 处理最近的待处理工件
                工件 待处理工件 = 主通道调度.Get工件(待处理工件s);

                //将工件挪到小车上面(并且等待移动完成)
                double posFrom = GetPos(待处理工件.CurrentWorkStation);
                Car Car = GetCar(待处理工件.CurrentWorkStation);
                Car.MoveStation(posFrom);
                //机械手提取工件
                Thread.Sleep(ProductLine.Instance.机械手提取工件时间);
                Car.Have工件 = true;//让小车拥有工件
                //移除工件
                待处理工件.CurrentWorkStation.Remove工件();
                double posTo = GetPos(待处理工件.NextWorkStation);
                Car.MoveStation(posTo);
                Thread.Sleep(ProductLine.Instance.机械手提取工件时间);//机械手提取工件
                Car.Have工件 = false;
                //重置移动之前的Lock
                lock (m_LockLis工件s)
                {
                    //解锁工件
                    待处理工件.CurrentWorkStation.IsLock = false;
                    //移除工件
                   
                    //下一个站点新增工件
                    待处理工件.NextWorkStation.Add工件(待处理工件);
                    待处理工件.IsWaitMove = false;//待处理工件
                    // Lis工件s.Remove(待处理工件);//移除待处理工件
                }
                //小车处理一台马上去另外一台 或者歇着
            }
        }

        public void DealCar(int groupID)
        {
            Car car = GetCar(groupID);
            while (true)
            {
                IEnumerable<工件> 待处理工件s;
                lock (m_LockLis工件s)
                {
                    //整理出待处理的工件
                    待处理工件s = Lis工件s.Where(x => x.IsWaitMove&&x.CurrentWorkStation.池子.GroupID== groupID);
                }

                //没有待处理工件,原地休息
                if (待处理工件s.Count() == 0)
                {
                    Thread.Sleep(100);
                    continue;
                }

                // 处理最近的待处理工件
                工件 待处理工件 = 主通道调度.Get工件(待处理工件s);

                //将工件挪到小车上面(并且等待移动完成)
                double posFrom = GetPos(待处理工件.CurrentWorkStation);
                bool isForm中途 = false;
                if (待处理工件.CurrentWorkStation.Station == this.公共Station)
                {
                    isForm中途 = true;
                }

                if (this.CarCount == 1)
                {
                    isForm中途 = false;
                }

                while (true)
                {
                    if (!isForm中途)
                    {
                        break;
                    }

                    lock (m_LockLis工件s)
                    {
                        if (!this.公共Station.IsLock)
                        {
                            this.公共Station.IsLock = true;
                            break;
                        }
                    }
                    //sleep在lock外面
                    Thread.Sleep(100);
                }

                //Car car = car;
                car.MoveStation(posFrom);
                //机械手提取工件
                Thread.Sleep(ProductLine.Instance.机械手提取工件时间);
                car.Have工件 = true;//让小车拥有工件
                car.工件 = 待处理工件;
                //移除工件
                待处理工件.CurrentWorkStation.Remove工件();
                double posTo = GetPos(待处理工件.NextWorkStation);
                bool 是否End中途 = false;
                if (待处理工件.NextStation == this.公共Station)
                {
                    是否End中途 = true;
                }

                if (this.CarCount == 1)
                {
                    是否End中途 = false;
                }

                while (true)
                {
                    if (isForm中途)
                    {
                        break;
                    }

                    if (!是否End中途)
                    {
                        break;
                    }

                    lock (m_LockLis工件s)
                    {
                        if (!待处理工件.NextStation.IsLock)
                        {
                            待处理工件.NextStation.IsLock = true;
                            break;
                        }
                    }
                    Thread.Sleep(100);
                }
                car.MoveStation(posTo);
                if (isForm中途&&(!是否End中途))
                {
                    this.公共Station.IsLock = false;
                }
                Thread.Sleep(ProductLine.Instance.机械手提取工件时间);//机械手提取工件
                car.Have工件 = false;
                car.工件 = null;
                //重置移动之前的Lock
                lock (m_LockLis工件s)
                {
                    //解锁工件
                    待处理工件.CurrentWorkStation.IsLock = false;
                    //移除工件

                    //下一个站点新增工件
                    待处理工件.NextWorkStation.Add工件(待处理工件);
                    待处理工件.IsWaitMove = false;//待处理工件
                    // Lis工件s.Remove(待处理工件);//移除待处理工件
                }
                //将小车移走 
                if (是否End中途)
                {
                    double freePos = GetFreePos(groupID);
                    car.MoveStation(freePos);
                    lock (m_LockLis工件s)
                    {
                       this.公共Station.IsLock = false;//解锁
                    }
                }

            }
        }

        public Car GetCar(int groupID)
        {
            Car car = Car1;
            if (groupID == 2)
            {
                car = Car2;
            }
            return car;
        }

        public double GetFreePos(int groupID)
        {
            if (groupID == 2)
            {
                return Car2FreePos;
            }
            return Car1FreePos;
        }

        /// <summary>
        /// 获取最近的小车
        /// </summary>
        /// <param name="item"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public Car GetNearCar(WorkStationRequestMsg item, out string error)
        {
            //todo 岳志峰 
            error = "";
            List<Car> leftCars = new();
            List<Car> rightCars = new();
            //将小车往左右延伸
            //取左边小车  取右边小车
            foreach (var car in Cars)
            {
                if (car.Point3D.X < item.WorkStation.Station.Point3D.X)
                {
                    leftCars.Add(car);
                }

                if (car.Point3D.X > item.WorkStation.Station.Point3D.X)
                {
                    rightCars.Add(car);
                }
            }

            //根据X位置得出位置
            Comparison<Car> comparison = (x, y) =>
            {
                if (x.Point3D.X == y.Point3D.X)
                {
                    return 0;
                }

                if (x.Point3D.X > y.Point3D.X)
                {
                    return 1;
                }
                else
                {
                    return -1;
                }
            };

            leftCars.Sort(comparison);
            leftCars.Reverse();//反转得到倒序
            rightCars.Sort(comparison);
            Car left = null;
            foreach (var car in leftCars)
            {
                //车子占用即无法使用 不能跨车调度车辆
                if (car.GetCanUse() == false)
                {
                    break;
                }
                left = car;
                break;
            }

            Car right = null;
            foreach (var car in rightCars)
            {
                if (car.GetCanUse() == false)
                {
                    break;
                }
                right = car;
                break;
            }

            //比较得出路径最短的小车
            if (left == null && right == null)
            {
                error = "此处调度左右卡主";
                return null;
            }

            if (left == null && right != null)
            {
                return right;
            }

            if (left != null && right == null)
            {
                return left;
            }

            double distanceLeft = Math.Abs(left.Point3D.X - item.WorkStation.Station.Point3D.X);
            double distanceRight = Math.Abs(right.Point3D.X - item.WorkStation.Station.Point3D.X);
            if (distanceLeft < distanceRight)
            {
                right.ReleaseLock();
                return left;
            }
            else
            {
                left.ReleaseLock();
                return right;
            }

        }

        /// <summary>
        /// 移动时获取途径站点
        /// </summary>
        /// <param name="fromStation"></param>
        /// <param name="toStation"></param>
        /// <returns></returns>
        public List<Station> Get途径Stations(Station fromStation, Station toStation)
        {
            List<Station> lisRets = new List<Station>();
            //找出途径的站点
            foreach (Station station in this.Stations)
            {
                //if (station.Point3D.X > fromStation.Point3D.X&&toStation.Point3D.X)
                //{

                //}
            }
            return lisRets;
        }

        /// <summary>
        /// 为片区加入工件(从主通道继承工件)
        /// </summary>
        /// <param name="工件"></param>
        /// <param name="workStation"></param>
        public void Add工件(工件 工件, WorkStation workStation)
        {
            workStation.Add工件(工件);
            工件.StartTime = DateTime.Now;
            工件.IsWaitMove = true;
            //workStation.IsWaitMove = true;
            工件.CurrentWorkStation = workStation;//当前槽位(非工作位时直接完成 )
            工件.CurrentStation = workStation.Station;//
            //得出工件下一个工作槽位
            工件.NextWorkStation = GetWorkStation(工件);//得出工件下一个槽位(提前锁定,)
            工件.NextStation = 工件.NextWorkStation.Station;
            //将工件信息录入片区 等待下一个片区使用
            lock (m_LockLis工件s)
            {
                Lis工件s.Add(工件);
            }
        }

        /// <summary>
        /// 交换工件(将工件从一个工位移动到另一个工位)
        /// </summary>
        /// <param name="工件"></param>
        public void Swap(工件 工件)
        {
            Car carFrom = GetStationCar(工件.CurrentStation);
            Car carTo = GetStationCar(工件.NextStation);
            //移动到工件位置
            carFrom.MoveStation(GetPos(工件.CurrentStation));
            小车从站点拿取工件(工件, carFrom, 工件.CurrentWorkStation);
            //起始点相同 用同一个小车调度即可

            if (carFrom == carTo)
            {
                carTo.MoveStation(GetPos(工件.NextStation));//移动到指定位置
                工件.CurrentWorkStation.IsLock = false;//解锁
                //小车拿取工件到槽位
                小车拿取工件到站点(工件, carTo, 工件.NextWorkStation);

                //不同池子对应不同处理方式
                switch (工件.NextWorkStation.池子.池子类型)
                {
                    case 池子类型.工作池子:
                        //
                        break;
                    case 池子类型.上料池子:
                        break;
                    case 池子类型.下料池子:
                        break;
                    case 池子类型.中途上料池子:
                        break;
                    case 池子类型.中途下料池子:
                        break;
                }
                //if(工件.WorkStation.is)
                //
            }
            else
            {
                //这里需要进入中途下料区域/ 中途上料区域。
                //这里需要去中途站点
                // 

            }
        }

        /// <summary>
        /// 小车从站点拿取工件
        /// </summary>
        /// <param name="工件"></param>
        /// <param name="workStation"></param>
        public void 小车从站点拿取工件(工件 工件, Car car, WorkStation workStation)
        {
            //小车从槽位拿取工件
            workStation.当前工件 = null;
            Thread.Sleep(300);
            car.Have工件 = true;
            car.工件 = 工件;
        }

        /// <summary>
        /// 小车从站点拿取工件
        /// </summary>
        /// <param name="工件"></param>
        /// <param name="workStation"></param>
        public void 小车拿取工件到站点(工件 工件, Car car, WorkStation workStation)
        {
            //小车从槽位拿取工件
            car.Have工件 = false;
            car.工件 = null;
            Thread.Sleep(300);
            workStation.当前工件 = 工件;

        }

        /// <summary>
        /// 获取位置
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public double GetPos(Station station)
        {
            return station.Point3D.X - PassVM.LineRigidBody.PointStartBase.X;
        }


        /// <summary>
        /// 获取位置
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public double GetPos(WorkStation workStation)
        {
            //if (workStation.池子 == null)
            //{
            //    return GetPos(workStation.Station);
            //}

            //return workStation.池子.PointStart.X - PassVM.LineRigidBody.PointStartBase.Y;
            return workStation.Station.Point3D.X - PassVM.LineRigidBody.PointStartBase.X;
        }

        //根据工位类型 找出相应工件的下一个槽位
        public WorkStation GetWorkStation(工件 工件)
        {
            //StepMode 
            工位类型 gwlx工位类型 = 工件.WorkStations[工件.Step];
            WorkStation nextWorkStation = null;
            bool haveFind = false;
            lock (m_LockLis工件s)
            {
                foreach (池子 池子 in this.池子s)
                {
                    if (池子.池子类型 != 池子类型.工作池子)
                    {
                        continue;
                    }

                    if (池子.工位类型.Name != gwlx工位类型.Name)
                    {
                        continue;
                    }

                    foreach (WorkStation workStation in 池子.Works)
                    {
                        //锁住的工站暂时不能使用
                        if (workStation.IsLock)
                        {
                            continue;
                        }
                        nextWorkStation = workStation;
                        haveFind = true;
                        break;
                        //return workStation;
                        //workStation.Add工件();
                    }

                    if (haveFind)
                    {
                        break;
                    }
                }

                if (haveFind)
                {
                    nextWorkStation.IsLock = true;
                    return nextWorkStation;
                }
                else
                {
                    //没有发现当前工位对应的槽位,这时候需要送到下料区域 。下料区域满了的情况下,将进行等待。


                }
            }



            return nextWorkStation;
            //这里有问题直接抛异常
            MessageAggregator<ErrorMsg>.Publish($"  找不到工件{工件.Name} 所需工位类型{gwlx工位类型.Name} 在片区{this.Name} 的下一个工位");
            return null;
        }

        /// <summary>
        /// 处理中间站点的小车  直接流走(可以直接沿用)
        /// </summary>
        /// <param name="workStation"></param>
        public void DealMidleWorkStation(WorkStation workStation)
        {
            while (true)
            {
                DealContinueRun(workStation);
                工件 工件 = workStation.当前工件;
                if (workStation.当前工件 == null)
                {
                    Thread.Sleep(100);
                    continue;
                }
            }
        }

        /// <summary>
        /// 只处理工作池子
        /// </summary>
        /// <param name="workStation"></param>
        public void DealWorkStation(WorkStation workStation)
        {
            if (workStation.池子 == null)
            {
                return;
            }

            if (workStation.池子.工位类型 == null)
            {
                return;
            }

            if (workStation.池子.池子类型 == 池子类型.None)
            {
                return;
            }
            while (true)
            {
                DealContinueRun(workStation);
                工件 工件 = workStation.当前工件;
                if (工件 == null)
                {
                    Thread.Sleep(100);
                    continue;
                }

                if (工件.IsWaitMove)
                {
                    Thread.Sleep(100);
                    continue;
                }

                //有工件进入工位,等待工作完成
                工件.StartTime = DateTime.Now;
                switch (workStation.池子.池子类型)
                {
                    case 池子类型.工作池子:
                        //工作池子需要等待工作完成
                        工件.工件状态 = 工件状态.工作中;
                        Thread.Sleep(workStation.池子.工位类型.Time*1);
                        工件.Step++;
                        工件.StartTime=DateTime.Now;
                        break;
                    //上下料池子 
                    case 池子类型.上料池子:
                        //通知主通道 
                        lock (m_LockLis工件s)
                        {
                            Lis工件s.Add(工件);
                        }
                        break;
                    case 池子类型.下料池子:
                        //下料池子让主通道处理
                        lock (m_LockLis工件s)
                        {
                            Lis工件s.Remove(工件);
                        }
                        //通知主通道(让主通道来处理)
                        //需要得出下一个片区
                        ProductLine.Instance.主通道调度.MoveNext片区(workStation, 工件);
                        while (true)
                        {
                            if (workStation.当前工件 == null)
                            {
                                break;
                            }
                            Thread.Sleep(100);
                        }
                        //ProductLine.Instance.主通道调度.Add(工件); //交给主通道调度 
                        //需要得出小车
                        continue;
                    case 池子类型.中途上料池子:
                        //通知小车来上料
                        break;
                    case 池子类型.中途下料池子:
                        //直接移动到下料
                        break;
                }
                工件.工件状态 = 工件状态.等待运输中;
                池子类型 czlx = 池子类型.None;

                //这里所有步骤执行完毕(等待完成)
                if (工件.Step == 工件.WorkStations.Count)
                {
                    //移动到下料(直接)
                    if (workStation.池子.GroupID == 1)
                    {
                        czlx = 池子类型.下料池子;

                    }
                    else
                    {
                        czlx = 池子类型.中途下料池子;
                    }
                    Deal下料(workStation, 工件, czlx);
                    while (true)
                    {
                        if (workStation.当前工件 == null)
                        {
                            break;
                        }
                        Thread.Sleep(100);
                    }
                    continue;
                }
                工位类型 gwlx工位类型 = 工件.WorkStations[工件.Step];

                bool haveNext = false;
                bool isSameGroup = true;
                foreach (池子 池子 in this.池子s)
                {
                    if (池子.池子类型 != 池子类型.工作池子)
                    {
                        continue;
                    }

                    if (池子.GroupID != workStation.池子.GroupID)
                    {
                        continue;
                    }

                    if (池子.工位类型.Name == gwlx工位类型.Name)
                    {
                        haveNext = true;
                        break;
                    }
                }

                if (!haveNext)
                {
                    foreach (池子 池子 in this.池子s)
                    {
                        if (池子.池子类型 != 池子类型.工作池子)
                        {
                            continue;
                        }

                        if (池子.GroupID == workStation.池子.GroupID)
                        {
                            continue;
                        }

                        if (池子.工位类型.Name == gwlx工位类型.Name)
                        {
                            haveNext = true;
                            isSameGroup = false;
                            break;
                        }
                    }
                }

               

                //如果下一个工位类型在这个片区 ,移动到指定片区,否则移动到下料位置
                


                if (haveNext)
                {
                    //移动到指定位置
                    if (isSameGroup)
                    {
                        while (true)
                        {
                            bool haveDeal = Deal工位类型(工件, workStation, 池子类型.工作池子, gwlx工位类型);
                            if (!haveDeal)
                            {
                                Thread.Sleep(100);
                                continue;
                            }
                            break;
                        }
                    }
                    else
                    {
                        if (workStation.池子.GroupID == 1)
                        {
                            czlx = 池子类型.中途上料池子;
                        }
                        else
                        {
                            czlx = 池子类型.中途下料池子;
                        }
                        Deal下料(workStation, 工件, czlx);

                    }

                }
                else
                {
                    if (workStation.池子.GroupID == 1)
                    {
                        czlx = 池子类型.下料池子;
                        
                    }
                    else
                    {
                        czlx = 池子类型.中途下料池子;
                    }
                    Deal下料(workStation, 工件, czlx);
                    //两个小车一起下料(中途下料池子)

                }

                //等待工件被移走 等待下一个工件进入
                while (true)
                {
                    if (workStation.当前工件 == null)
                    {
                        break;
                    }
                    Thread.Sleep(100);
                }
            }
        }

        public void Deal下料(WorkStation workStation,工件 工件, 池子类型 czlx)
        {
           

            //处理下料
            while (true)
            {
                bool ret = Deal工位类型(工件, workStation, czlx);
                if (ret)
                {
                    break;
                }
                else
                {
                    Thread.Sleep(100);
                }
            }
        }

        

        /// <summary>
        /// 
        /// </summary>
        /// <param name="工件"></param>
        /// <param name="workStation"></param>
        /// <param name="池子类型"></param>
        /// <returns></returns>
        public bool Deal工位类型(工件 工件, WorkStation workStation, 池子类型 池子类型)
        {
            bool haveFind = false;
            WorkStation nextWorkStation = null;
            DealContinueRun(workStation);

            //到前面站点
            foreach (池子 池子 in 池子s)
            {
                if (池子.池子类型 != 池子类型)
                {
                    continue;
                }

                lock (m_LockLis工件s)
                {
                    foreach (WorkStation itemWorkStation in 池子.Works)
                    {
                        if (itemWorkStation.IsLock)
                        {
                            continue;
                        }
                        itemWorkStation.IsLock = true;
                        haveFind = true;
                        nextWorkStation = itemWorkStation;
                        break;
                    }
                }

                if (haveFind)
                {
                    break;
                }
            }

            if (haveFind)
            {
                //为工件进入主系统循环解锁
                工件.NextStation = nextWorkStation.Station;
                工件.NextWorkStation = nextWorkStation;
                //工件.StartTime = DateTime.Now;
                工件.IsWaitMove = true;
                return true;
            }
            else
            {
                return false;
            }

        }

        /// <summary>
        /// 处理
        /// </summary>
        /// <param name="工件"></param>
        /// <param name="workStation"></param>
        /// <param name="池子类型"></param>
        /// <returns></returns>
        public bool Deal工位类型(工件 工件, WorkStation workStation, 池子类型 池子类型, 工位类型 gwlx工位类型)
        {
            bool haveFind = false;
            WorkStation nextWorkStation = null;
            DealContinueRun(workStation);

            //到前面站点
            foreach (池子 池子 in 池子s)
            {
                if (池子.池子类型 != 池子类型)
                {
                    continue;
                }

                if (池子.工位类型.Name != gwlx工位类型.Name)
                {
                    continue;
                }

                //先找一样的池子
                if (workStation.池子.GroupID != 池子.GroupID)
                {
                    continue;
                }

                lock (m_LockLis工件s)
                {
                    foreach (WorkStation itemWorkStation in 池子.Works)
                    {
                        if (itemWorkStation.IsLock)
                        {
                            continue;
                        }
                        itemWorkStation.IsLock = true;
                        haveFind = true;
                        nextWorkStation = itemWorkStation;
                        break;
                    }
                }

                if (haveFind)
                {
                    break;
                }
            }

            bool isSameGroup = true;

            if (!haveFind)
            {
                foreach (池子 池子 in 池子s)
                {
                    if (池子.池子类型 != 池子类型)
                    {
                        continue;
                    }

                    if (池子.工位类型.Name != gwlx工位类型.Name)
                    {
                        continue;
                    }

                    //没有找到找不一样的池子
                    if (workStation.池子.GroupID == 池子.GroupID)
                    {
                        continue;
                    }

                    lock (m_LockLis工件s)
                    {
                        foreach (WorkStation itemWorkStation in 池子.Works)
                        {
                            if (itemWorkStation.IsLock)
                            {
                                continue;
                            }
                            //itemWorkStation.IsLock = true;
                            //nextWorkStation = itemWorkStation;
                            haveFind = true;
                            isSameGroup = false;
                            break;
                        }
                    }

                    if (haveFind)
                    {
                        break;
                    }
                }
            }

            if (haveFind)
            {
                //为工件进入主系统循环解锁 ()
                if (isSameGroup)
                {
                    工件.NextStation = nextWorkStation.Station;
                    工件.NextWorkStation = nextWorkStation;
                    //工件.StartTime = DateTime.Now;
                    工件.IsWaitMove = true;
                    return true;
                }
                else
                {
                    //移动到中间上料位,由中间上料位处理
                    while (true)
                    {
                        //到中途上料池子去等待
                        bool ret = Deal工位类型(工件, workStation, 池子类型.中途上料池子);
                        if (ret)
                        {
                            break;
                        }
                        else
                        {
                            Thread.Sleep(100);
                        }
                        break;
                    }
                    return true;
                }

            }
            else
            {
                return false;
            }

        }

        public static void DealContinueRun(WorkStation workStation)
        {
            while (true)
            {
                if (workStation.IsContinueRun)
                {
                    break;
                }
                Thread.Sleep(1000);
            }
        }

    }



    public enum 码头状态
    {

    }

    /// <summary>
    /// 摆渡(这里用直线段,这里是不用考虑所属通道，框架为全图流,也有所属PassVM)
    /// </summary>
    [Serializable]
    [JsonObject(MemberSerialization.OptOut)]
    public class BoatVM : PassVM
    {


        /// <summary>
        /// 备用摆渡(替补队员)
        /// </summary>
        [Reactive] public BoatVM BackupBoatVm { get; set; }



        /// <summary>
        /// 碰撞半径(只有一个小车的2时候不用考虑碰撞半径,这里多个摆渡需要考虑碰撞半径)
        /// </summary>
        [Reactive] public double RadiusDistance { get; set; } = 100;

        /// <summary>
        /// 摆渡有属于摆渡的轨道
        /// </summary>
        [Reactive] public PassVM PassVM { get; set; }

        /// <summary>
        /// 当前摆渡上的小车 可为空
        /// </summary>
        [Reactive] public Car CurrentCar { get; set; }

        /// <summary>
        /// 移动到指定站点
        /// </summary>
        /// <param name="toStation"></param>
        public void MoveStation(Station toStation)
        {
            // 移动之前锁死边

        }


        public void MoveStation(Station formStation, Station toStation)
        {
            //while ()
            //{

            //}

            //进入竹
            //if (toStation.是否主通道站点)
            //{
            //    if (this.P)
            //}
        }

        /// <summary>
        /// 不能进入主通道需要释放
        /// </summary>
        /// <param name="toStation"></param>
        /// <returns></returns>
        public bool 判断能否进入主通道(Station toStation)
        {
            if (!toStation.是否主通道站点)
            {
                return true;
            }

            if (this.CurrentCar == null)
            {
                return true;
            }

            return false;
        }



    }




}
